/* Copyright (C) 2019 Patrick G. Durand
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.plealog.genericapp.ui.common;

import javax.swing.*;
import javax.swing.border.Border;
import javax.swing.border.EmptyBorder;
import java.awt.*;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.io.Serial;

/**
 * A sample component aims at displaying check boxes within a JList.
 * This is a utility class to be used with CheckBoxChooserDialog.
 *
 * @author Patrick G. Durand
 */
//adapted from https://stackoverflow.com/questions/19766/how-do-i-make-a-list-with-checkboxes-in-java-swing 
public class JCheckBoxList extends JList<JCheckBox> {
	@Serial
	private static final long serialVersionUID = -1260025907269942772L;
	protected static Border noFocusBorder = new EmptyBorder(1, 1, 1, 1);

	public JCheckBoxList() {
		setCellRenderer(new CellRenderer());
		//redirect JList mouse click to JCheckBox
		addMouseListener(new MouseAdapter() {
			public void mousePressed(MouseEvent e) {
				int index = locationToIndex(e.getPoint());
				if (index != -1) {
					JCheckBox checkbox = getModel().getElementAt(index);
					checkbox.setSelected(!checkbox.isSelected());
					repaint();
				}
			}
		});
		//handle keyboard appropriately
		addKeyListener(new KeyAdapter() {
			@Override
			public void keyPressed(KeyEvent e) {
				int index = getSelectedIndex();
				if (index != -1 && e.getKeyCode() == KeyEvent.VK_SPACE) {
					boolean newVal = !getModel()
							.getElementAt(index).isSelected();
					for (int i : getSelectedIndices()) {
						JCheckBox checkbox = getModel()
								.getElementAt(i);
						checkbox.setSelected(newVal);
						repaint();
					}
				}
			}
		});
		setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
	}

	public JCheckBoxList(ListModel<JCheckBox> model) {
		this();
		setModel(model);
	}

	protected class CellRenderer implements ListCellRenderer<JCheckBox> {
		public Component getListCellRendererComponent(
				JList<? extends JCheckBox> list, JCheckBox value, int index,
				boolean isSelected, boolean cellHasFocus) {
			value.setBackground(isSelected ? getSelectionBackground()
					: getBackground());
			value.setForeground(isSelected ? getSelectionForeground()
					: getForeground());
			value.setEnabled(isEnabled());
			value.setFont(getFont());
			value.setFocusPainted(false);
			value.setBorderPainted(true);
			value.setBorder(isSelected ? UIManager
					.getBorder("List.focusCellHighlightBorder") : noFocusBorder);
			return value;
		}
	}
}

